﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UtilZ.Dotnet.Ex.Base;

namespace UtilZ.Dotnet.Ex.Communication.Net.Web
{
    /// <summary>
    /// 文本消息
    /// </summary>
    public class WebSocketTextMessage : WebSocketMessageAbs
    {
        private readonly string _text;
        /// <summary>
        /// 获取消息文本
        /// </summary>
        public string Text
        {
            get { return _text; }
        }

        private readonly Encoding _textEncoding;

        /// <summary>
        /// 构造函数
        /// </summary>
        internal WebSocketTextMessage(string text, Encoding textEncoding)
            : base(WebSocketMessageTypes.Text)
        {
            this._text = text;
            this._textEncoding = textEncoding;
        }


        /// <summary>
        /// 获取操作码
        /// </summary>
        /// <returns>操作码</returns>
        protected override byte PrimitiveGetOpcode()
        {
            return HttpOpcodes.TEXT_FRAME;
        }


        private byte[] _totalData = null;
        private int _sendOffset = 0;
        /// <summary>
        /// 获取本次发送帧的数据(返回true表示还有数据需要发送,返回false表示最后一帧数据)
        /// </summary>
        /// <param name="frameInfo">帧数据</param>
        /// <returns>true表示还有数据需要发送,返回false表示最后一帧数据</returns>
        protected override void GetFrameData(FrameInfo frameInfo)
        {
            if (this._totalData == null)
            {
                byte[] data = this._textEncoding.GetBytes(this._text);
                if (data.Length < frameInfo.FrameMaxSize)
                {
                    frameInfo.FrameIndex = 1;
                    frameInfo.FrameCount = 1;
                    frameInfo.FrameData = data;
                    return;
                }

                this._totalData = data;
                int frameCount = data.Length / frameInfo.FrameMaxSize;
                if (data.Length % frameInfo.FrameMaxSize > 0)
                {
                    frameCount++;
                }

                frameInfo.FrameCount = frameCount;
            }

            int frameDataLen = frameInfo.FrameMaxSize;
            int mod = this._totalData.Length - this._sendOffset;
            if (mod < frameInfo.FrameMaxSize)
            {
                frameDataLen = mod;
            }
            frameInfo.FrameData = this._totalData.Skip(this._sendOffset).Take(frameDataLen).ToArray();
            frameInfo.FrameIndex = this._sendOffset / frameInfo.FrameMaxSize + 1;
            this._sendOffset += frameDataLen;
        }
    }
}
